/* eslint-disable max-len */
// vue-i18n@9 版本
import { createI18n } from 'vue-i18n';

// 当前语言
let currentLanguage = '';
// 回退语言
let fallbackLanguage = '';
// 传入的语言包
let defaultMssages = {};
// 当前项目的所有语言列表
let languageList = [];
// 当前语言文档
let languageSheet = null;
// 语言文档接口地址
let URL = '';
// 项目代码
let proCode = '';
let i18n = null;

class LoadingMask {
    constructor(config) {
        const { loadingText, duration } = config || {};
        if (window && document) {
            const spinnerId = 'spinner-2024';
            this.spinner = document.querySelector(`#${spinnerId}`);
            if (!this.spinner) {
                const spinner = document.createElement('div');
                spinner.id = spinnerId;
                spinner.innerHTML = `
                    <div style="position:fixed;left:0;right:0;top:0;bottom:0;z-index:1008611;background-color:rgba(250,250,250,0.8);">
                        <div style="position:absolute;left:50%;top:50%;width:70px;height:70px;border:5px solid #f2f2f2;border-top:5px solid #1ab7b1;border-radius:50%;animation:spin 1s linear infinite;box-sizing:border-box;background:#ffffff;"></div>
                        <div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:50px;color:#1ab7b1;font-size:12px;">${loadingText || ''}</div>
                        <style>@keyframes spin {0%{transform:translate(-50%,-50%) rotate(0deg);}100%{transform:translate(-50%,-50%) rotate(360deg);}}</style>
                    </div>
                `;
                document.body.append(spinner);
                this.spinner = spinner;
            } else {
                this.spinner.style.transition = '0s';
                this.spinner.style.opacity = 1;
                this.spinner.style.display = 'block';
            }
            if (duration > 0) setTimeout(this.stop.bind(this), duration);
        }
    }

    stop() {
        if (this.spinner) {
            this.spinner.style.transition = '0.5s';
            this.spinner.style.opacity = 0;
            setTimeout(() => {
                this.spinner.style.display = 'none';
            }, 1000);
        }
    }
}

// 获取项目语言列表
const initLanguageList = () => {
    languageList = [];
    const url = `${URL}/system/admin/app/project/languages?code=${proCode}`;
    return new Promise((resolve) => {
        fetch(url).then(async (response) => {
            if (!response.ok) return;
            const res = await response.json();
            languageList = (res.data || []).map((d) => ({ ...d, code: (d.code || '').replace('-', '_') }));
            resolve(languageList);
        }).catch(() => resolve());
    });
};

// 根据指定语言code获取项目语言文档
const initLanguageSheet = (lang) => {
    lang = lang || currentLanguage;
    const langConfig = languageList.find(({ code }) => code === lang);
    if (!langConfig || !langConfig.translateUrl) return Promise.resolve();
    languageSheet = null;
    return new Promise((resolve) => {
        fetch(langConfig.translateUrl).then(async (response) => {
            if (!response.ok) {
                resolve();
                return;
            }
            const res = await response.json();
            if (res && Object.keys(res).length) {
                languageSheet = res;
                currentLanguage = lang;
            }
            resolve(languageSheet);
        }).catch(() => resolve());
    });
};

// 切换当前语言类型
export const changeLang = (lang) => {
    lang = (lang || '').replace('-', '_');
    return new Promise((resolve, reject) => {
        const targetMessage = i18n.global.messages[lang] || {};
        if (targetMessage._IS_LOADED) {
            i18n.global.locale = lang;
            currentLanguage = lang;
            window.localStorage.setItem('sys_lang', currentLanguage);
            resolve();
            return;
        }
        if (!languageList.find(({ code }) => code === lang)) {
            reject();
            return;
        }
        const loading = new LoadingMask();
        initLanguageSheet(lang).then(() => {
            if (languageSheet || defaultMssages[lang]) {
                i18n.global.mergeLocaleMessage(lang, {
                    ...(defaultMssages[lang] || {}),
                    ...(languageSheet || {}),
                    // 是否成功加载了远程语言包
                    _IS_LOADED: !!languageSheet,
                });
                i18n.global.locale = lang;
                currentLanguage = lang;
                window.localStorage.setItem('sys_lang', currentLanguage);
                resolve();
                return;
            }
            reject();
        }).catch(() => { reject(); }).finally(loading.stop.bind(loading));
    });
};

// 获取当前语言类型方法封装
export const getCurrentLang = () => i18n.global.locale;

// 获取项目所配置的语言列表
export const getLanguageList = () => languageList;

// 获取i18n对象
export const useI18n = () => i18n;

export default async (app, config) => {
    // eslint-disable-next-line object-curly-newline
    const { projectCode, baseURL, locale, fallbackLocale, messages, fallbackMessage } = config || {};
    const storageLang = window.localStorage.getItem('sys_lang');
    defaultMssages = messages || {};
    fallbackLanguage = fallbackLocale || 'en_US';
    currentLanguage = (locale || storageLang || '').replace('-', '_') || fallbackLanguage;
    if (baseURL && projectCode) {
        URL = baseURL[baseURL.length - 1] === '/' ? baseURL.slice(0, baseURL.length - 1) : baseURL;
        proCode = projectCode;
        const loading = new LoadingMask();
        await initLanguageList();
        await initLanguageSheet();
        if (!languageSheet && !defaultMssages[currentLanguage]) currentLanguage = fallbackLanguage;
        loading.stop();
    }
    i18n = await createI18n({
        locale: currentLanguage,
        fallbackLocale: fallbackLanguage,
        messages: { [currentLanguage]: { ...(defaultMssages[currentLanguage] || fallbackMessage || {}), ...(languageSheet || {}), } },
    });
    window.localStorage.setItem('sys_lang', currentLanguage);
    app.use(i18n);
    return i18n;
};
